# -*- coding: utf-8 -*-
"""
    Project name：code_potentialflow
# -------------------------------
    File name：cases.py
    Created on：2025/4/10 14:29
    Author：(input)
    Description: 案例文件
"""
import numpy as np

from parasolver import ParameterSolver
from sourcesink import SourceSink
from grid import PhysicalGrid, AuxiliaryGrid
from drawfigs import SosiFlowPlotter

from analysis import FlowAnalyzer


def case_sosi():
    """
    源汇对在矩形中的流动问题
    开题汇报时的案例case
    房间参数：length=5.0m, height=3.0m

    送风参数：inlet_vlc = 40m/s
            source_strength = inlet_vlc * d_inlet*1m
            sink_strength = source
            Q = 2
    风口位置参数： mid distance:距离房间中心的距离 2.4m
                floor distance：距离地板的距离3.0m
    """
    # 房间参数定义
    length = 5.0
    height = 3.0
    # 送回风位置定义mid distance、floor distance
    md = 2.4
    fd = height
    # 送回风强度定义
    inlet_vlc = 40 # 风速m/s
    inlet_A = 0.05 * 1 # 风口面积m^2
    so_strn = inlet_vlc * inlet_A # 源强m^3/s
    si_strn = -so_strn # 汇强

    N = 50 # 流动域网格数量

    # SC变换参数计算
    solver = ParameterSolver(length, height)
    result = solver.solve()
    if result:
        C, k, k_prime = result
        print(f"计算结果：C={C}, k={k}, k'={k_prime}")

    # 创建物理平面网格
    phys_grid = PhysicalGrid(length, height, N, C, k)

    # 映射：物理平面 -> 辅助平面
    W_mapped = phys_grid.sc_inverse(phys_grid.Z)

    # 创建辅助平面网格
    aux_grid = AuxiliaryGrid(W_mapped)

    # 在物理平面上放置源汇（送风口和回风口）
    # 送、回风口复数坐标
    z_source = -md + 1.0j*fd
    z_sink = md + 1.0j*fd
    # 源和汇的强度
    sosi_strn = (so_strn, si_strn)
    # 源汇实例
    source_sink = SourceSink(sosi_strn, z_source, z_sink, C, k, length, height)
    # 计算复势、流函数、速度场、压力
    _, phi, psi = source_sink.cplx_W(phys_grid.X, phys_grid.Y)
    magV, u_vel, v_vel = source_sink.cplx_velocity(phys_grid.X, phys_grid.Y)
    #p, CP, d_v2 = source_sink.pressure(U_ref=1.0, magV=magV, u_vel=u_vel, v_vel=v_vel)

    # 绘图可视化
    # 绘图实例
    plotter = SosiFlowPlotter(phys_grid, aux_grid, source_sink)

    # 绘制物理平面上的流函数
    #plotter.plot_psi(psi, title='Stream Function (Physical Plane)', is_physical=True)

    # 绘制辅助平面上的流函数
    #plotter.plot_psi(psi, title='Stream Function (Auxiliary Plane)', is_physical=False)

    # 绘制物理平面上的势函数
    #plotter.plot_phi(phi, title='Potential Function (Physical Plane)', is_physical=True)

    # 绘制物理平面上的流网图
    #plotter.plot_flow_net(phi, psi, title='Flow Net (Physical Plane)', is_physical=True)

    # 绘制物理平面上的速度场
    plotter.plot_velocity_field(u_vel, v_vel, magV=magV, show_magnitude=True, title='Velocity Field (Physical Plane)', is_physical=True)

    # 绘制物理平面上的压力分布
    #plotter.plot_pressure(CP, title='Pressure Coefficient Distribution (Physical Plane)', is_physical=True)

    # 导出物理量数据
    df = source_sink.export_field_data(phys_grid.X, phys_grid.Y, U_ref=1.0, to_csv=True,
                                       filename="debug_case_sosi.csv")

    # 创建 FlowAnalyzer 对象
    analyzer = FlowAnalyzer(df)

    # 分析速度分布并绘制不同速度范围的区域分布，使用裁剪
    analyzer.plot_velocity_distribution_regions(bins=5, clip_range=(1, 99), scatter_size=None)

    print("case_sosi结束！")

def case_sosi_ND():
    """
    源汇对在矩形中的流动问题(无量纲描述)

    房间参数：length=5.0m, height=3.0m
    特征参数： character=height
    送风参数：inlet_vlc = 40m/s
            source_strength = inlet_vlc * d_inlet*1m
            sink_strength = source
    风口位置参数： mid distance:距离房间中心的距离 2.4m
                floor distance：距离地板的距离3.0m
    """
    # 房间参数定义
    length_phy = 5.0
    height_phy = 3.0
    # 特征参数定义
    character = height_phy
    # 送回风位置定义mid distance、floor distance
    md_phy = 2.4
    fd_phy = height_phy

    # 输入：
    # 房间参数定义
    length = length_phy/character
    height = height_phy/character
    # 送回风位置定义mid distance、floor distance
    md = md_phy/character
    fd = fd_phy/character
    # 送回风强度定义
    inlet_vlc = 40 # 风速m/s
    inlet_A = 0.05 * 1 # 风口面积m^2
    so_strn = inlet_vlc * inlet_A # 源强m^3/s
    si_strn = -so_strn # 汇强

    N = 50 # 流动域网格数量

    # SC变换参数计算
    solver = ParameterSolver(length, height, dimensional=False)
    result = solver.solve()
    if result:
        C, k, k_prime = result
        print(f"计算结果：C={C}, k={k}, k'={k_prime}")

    # 创建物理平面网格
    phys_grid = PhysicalGrid(length, height, N, C, k)

    # 映射：物理平面 -> 辅助平面
    W_mapped = phys_grid.sc_inverse(phys_grid.Z)

    # 创建辅助平面网格
    aux_grid = AuxiliaryGrid(W_mapped)

    # 在物理平面上放置源汇（送风口和回风口）
    # 送、回风口复数坐标
    z_source = -md + 1.0j*fd
    z_sink = md + 1.0j*fd

    # 源和汇的强度
    sosi_strn = (so_strn, si_strn)
    # 源汇实例
    source_sink = SourceSink(sosi_strn, z_source, z_sink, C, k, length, height)
    # 计算复势、流函数、速度场、压力
    _, phi, psi = source_sink.cplx_W(phys_grid.X, phys_grid.Y)
    magV, u_vel, v_vel = source_sink.cplx_velocity(phys_grid.X, phys_grid.Y)
    #p, CP, d_v2 = source_sink.pressure(U_ref=1.0, magV=magV, u_vel=u_vel, v_vel=v_vel)

    # 绘图可视化
    # 绘图实例
    plotter = SosiFlowPlotter(phys_grid, aux_grid, source_sink)

    # 绘制物理平面上的流函数
    #plotter.plot_psi(psi, title='Stream Function (Physical Plane)', is_physical=True)

    # 绘制辅助平面上的流函数
    #plotter.plot_psi(psi, title='Stream Function (Auxiliary Plane)', is_physical=False)

    # 绘制物理平面上的势函数
    #plotter.plot_phi(phi, title='Potential Function (Physical Plane)', is_physical=True)

    # 绘制物理平面上的流网图
    #plotter.plot_flow_net(phi, psi, title='Flow Net (Physical Plane)', is_physical=True)

    # 绘制物理平面上的速度场
    plotter.plot_velocity_field(u_vel, v_vel, magV=magV, show_magnitude=True, title='Velocity Field (Physical Plane)', is_physical=True)

    # 绘制物理平面上的压力分布
    #plotter.plot_pressure(CP, title='Pressure Coefficient Distribution (Physical Plane)', is_physical=True)

    # 导出物理量数据
    df = source_sink.export_field_data(phys_grid.X, phys_grid.Y, U_ref=1.0, to_csv=True,
                                       filename="debug_case_sosi_ND.csv")

    # 导出物理量数据
    df = source_sink.export_field_data(phys_grid.X, phys_grid.Y, U_ref=1.0, to_csv=True,
                                       filename="debug_case_sosi.csv")

    # 创建 FlowAnalyzer 对象
    analyzer = FlowAnalyzer(df)

    # 分析速度分布并绘制不同速度范围的区域分布，使用裁剪
    analyzer.plot_velocity_distribution_regions(bins=5, clip_range=(2, 99), scatter_size=None)

    print("case_sosi_ND结束！")